/********************************************************************************************/
/*																							*/
/*								Twn_SafeChecks.cpp											*/
/*																							*/
/*	Description:	this library contains functions to manage safety checks in manual		*/
/*					operative modes. The sample time is loaded from a registry key			*/
/*																							*/
/********************************************************************************************/

#define ALONE_TWN_SAFE_CHECKS
#include "Twn_SafeChecks.h"

int			sampleTime;
int			waitMreqDownNum;
int			waitMreqDownTime;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved){
	LONG	res;
	LPDWORD	type;
	LPBYTE	data;
	LPDWORD size;
	HKEY	hKey;
    DWORD	dwBufLen = MY_BUFSIZE;
	DWORD	active;
    
	size = 0;
	data = 0;
	type = 0;
	
	
	switch(fdwReason){ 
		case DLL_PROCESS_ATTACH:
			RegOpenKeyEx(	HKEY_LOCAL_MACHINE, 
							TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Twn_SafeChecks"),
							0,
							KEY_QUERY_VALUE,
							&hKey);
			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("SampleTime"),
									NULL,
									NULL,
									(LPBYTE)&active,
									&dwBufLen);
			if(res == ERROR_SUCCESS){
				sampleTime = (int)active;
			}

			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("WaitMreqDownNum"),
									NULL,
									NULL,
									(LPBYTE)&active,
									&dwBufLen);
			if(res == ERROR_SUCCESS){
				waitMreqDownNum = (int)active;
			}

			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("WaitMreqDownTime"),
									NULL,
									NULL,
									(LPBYTE)&active,
									&dwBufLen);
			if(res == ERROR_SUCCESS){
				waitMreqDownTime = (int)active;
			}

			RegCloseKey(hKey);
			break;
		default:
			break;
	}
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

/****************************************************************************************/
/*																						*/
/*	Function:		SafeChecks															*/
/*																						*/
/*	Description:	Execute safety checks in manual operative modes.					*/
/*																						*/
/*	Return:			RETSTAT		-	RT_NORMAL for normal finish							*/
/*									RT_FAILED otherwise									*/
/*																						*/
/*	Author:			M. Tavella															*/
/*																						*/
/*	Date:			30/04/2002															*/
/*																						*/
/****************************************************************************************/
RETSTAT SafeChecks(void){
	RETSTAT		retSt;
	RETCOND		retCnd;
	TAGIDX		tagMmFAGRIdx;
	TAGIDX		tagStartMovIdx;
	TAGIDX		tagMMnoDownIdx;
	TAGVALEX	tagVal;
	float		px, py;
	int			vx, vy;
	GENIDX		zoneIdx;
	GENIDX		movingMast;
	int			dir;

	//Nomi tag movimento su asse Z//
	retCnd = GetTagIdx(TWN_FAGR_MREQ, &tagMmFAGRIdx);
	if(retCnd != RT_NORMAL)
		return(RT_FAILED);
	retCnd = GetTagIdx(TWN_START_MOV, &tagStartMovIdx);
	if(retCnd != RT_NORMAL)
		return(RT_FAILED);
	retCnd = GetTagIdx(TWN_MM_NO_DOWN, &tagMMnoDownIdx);
	if(retCnd != RT_NORMAL)
		return(RT_FAILED);
	
	ZeroMemory(&tagVal, sizeof(TAGVALEX));
	tagVal.qual.b.q1imp = 1;

	while(1){
		retSt = GetMovingMast(tagStartMovIdx, tagMmFAGRIdx, &movingMast, &dir);
		if(retSt != RT_NORMAL)
			goto SLEEP;
		switch(movingMast){
		case MAIN_MAST:
			if(dir == MOVING_DOWNWARD){
				retSt = GetMastPosInfiSC(MAIN_MAST, &px, &py, &zoneIdx);
				if(retSt != RT_NORMAL)
					goto SLEEP;
				else{
					retSt = GetZonePhisVirtCoord(px, py, &vx, &vy);
					if(retSt != RT_NORMAL){
						//Scrittura tag inibizione movimento MM//
						retSt = VotedTagWrite(TWN_MM_NO_DOWN, 1, 0, DIG_VALUE);
						if(retSt != RT_NORMAL)
							return(retSt);
						waitForMreqDown();
						goto SLEEP;
					}
					else{
						retSt =  CheckInsertFeasibility(MAIN_MAST, vx, vy);
						if(retSt != RT_NORMAL){
							//Scrittura tag inibizione movimento MM//
							retSt = VotedTagWrite(TWN_MM_NO_DOWN, 1, 0, DIG_VALUE);
							if(retSt != RT_NORMAL)
								return(retSt);
							waitForMreqDown();
						}
						goto SLEEP;
					}
				}
			}
			break;
		default:
			goto SLEEP;
			break;
		}
		
SLEEP:
	Sleep(sampleTime);
	}

	return(RT_NORMAL);
}

/****************************************************************************************/
/*																						*/
/*	Function:		waitForMreqDown														*/
/*																						*/
/*	Description:	Wait for FA gripper movment request value = 0 then clear busy cell	*/
/*					interlock.															*/
/*																						*/
/*	Return:			RETSTAT		-	RT_NORMAL for normal finish							*/
/*									RT_FAILED otherwise									*/
/*																						*/
/*	Author:			M. Tavella															*/
/*																						*/
/*	Date:			14/06/2002															*/
/*																						*/
/****************************************************************************************/
RETSTAT waitForMreqDown(void){
	RETCOND		retCnd;
	RETSTAT		retSt;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	int			i;

	retCnd = GetTagIdx(TWN_FAGR_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	for(i = 0; i < waitMreqDownNum; i++){
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(GtBit((short int)(tagVal.value.val_di), 15) == 0){
			retSt = VotedTagWrite(TWN_MM_NO_DOWN, 0, 0, DIG_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
			return(RT_NORMAL);
		}

		Sleep(waitMreqDownTime);
	}

	return(RT_FAILED);
}